<!--
 扇形
 @Author: mosowe
 @Date:2023-08-10 15:32:28
-->

<template>
  <view
    class="sector-componnet"
    :style="{
      '--point-x': threePoint[0],
      '--point-y': threePoint[1],
      '--index-rotate': props.index * props.angle + 'deg',
      '--bg-color': props.bgColor,
      '--color': props.color,
      '--size': props.size,
      '--text-angle': props.angle / 2 - 45 + 'deg',
      '--text-origin': props.radius + 'rpx',
      '--text-translate-x-y': translateXY,
      '--radius': -props.radius + 'rpx',
      '--text-position': -(props.radius / 6) * 5 + 'rpx',
      '--image-size': props.imageSize || '30rpx',
    }"
  >
    <view class="text-wrap">
      <view
        class="text"
        :class="{
          hasImage: props.image && props.text,
          justImage: props.image && !props.text,
        }"
      >
        <text class="title" v-if="props.text">
          {{ props.text }}
        </text>
        <image v-if="props.image" :src="props.image" class="image"></image>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { computed } from 'vue'

interface Props {
  text?: string
  angle?: number
  index?: number
  bgColor?: string
  color?: string
  size?: string
  radius?: number
  image?: string
  imageSize?: string
}

const props = withDefaults(defineProps<Props>(), {
  text: '测试',
  angle: 45,
  index: 0,
  bgColor: '#ff0000',
  size: '24rpx',
  color: '#fff',
  radius: 300,
  image: '',
  imageSize: '60rpx',
})

const threePoint = computed(() => {
  if (props.angle < 0 || props.angle > 180) {
    console.error('弧度值取值范围为0~180之间，当前值：' + props.angle)
    return [0, 0]
  }
  const a = (props.angle <= 90 ? props.angle : 180 - props.angle) * (Math.PI / 180) // 弧度转角度
  const r = props.radius
  let x: string = '0%'
  let y: string = '0%'
  if (props.angle > 90) {
    y = '0%'
    x = (((r + r * Math.cos(a)) / 2 / r) * 100).toFixed(2) + '%'
  } else if (props.angle === 90) {
    x = '50%'
    y = '0%'
  } else {
    y = (((r - r * Math.sin(a)) / 2 / r) * 100).toFixed(2) + '%'
    x = (((r - r * Math.cos(a)) / 2 / r) * 100).toFixed(2) + '%'
  }
  return [x, y]
})

const translateXY = computed(() => {
  return (Math.sqrt(props.radius * props.radius * 2) - props.radius - 30).toFixed(0) + 'rpx'
})
</script>

<style lang="scss" scoped>
.sector-componnet {
  width: 100%;
  height: 100%;
  background-color: var(--bg-color);
  border-radius: 50%;
  position: absolute;
  left: 0;
  top: 0;
  clip-path: polygon(0 0, 0 50%, 50% 50%, var(--point-x) var(--point-y));
  transform: rotate(calc(var(--index-rotate) + 90deg));
  .text-wrap {
    transform-origin: var(--text-origin) var(--text-origin);
    transform: rotate(var(--text-angle)) translateX(var(--text-translate-x-y))
      translateY(var(--text-translate-x-y));
  }
  .text {
    writing-mode: vertical-rl;
    font-size: var(--size);
    color: var(--color);
    font-weight: bold;
    transform: rotate(-45deg) translateX(75%);
    margin-top: 30rpx;
    vertical-align: middle;
    /* #ifdef MP-WEIXIN */
    transform: rotate(-45deg) translateX(50%);
    /* #endif */
    &.justImage {
      transform: rotate(-45deg);
    }
    &.hasImage {
      transform: rotate(-45deg) translateX(calc(var(--image-size) / 2));
      /* #ifdef MP-WEIXIN */
      transform: rotate(-45deg) translateX(45%);
      /* #endif */
    }
    .title {
      vertical-align: middle;
    }
    .image {
      display: inline-block;
      width: var(--image-size);
      height: var(--image-size);
      vertical-align: middle;
    }
  }
}
</style>
